home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / libg_261.zip / libg_261 / libg++ / src / dynamic_lib.c < prev    next >
C/C++ Source or Header  |  1991-08-14  |  4KB  |  204 lines

  1. /* 
  2.  *  dynamic_lib.c:    Dynamic Library Initialization for Unix
  3.  *  Author:           James Kempf
  4.  *  Created On:       Fri Apr  5 08:34:47 1991
  5.  *  Last Modified By: James Kempf
  6.  *  Last Modified On: Tue Aug  6 15:00:47 1991
  7.  *  Update Count:     14
  8.  */
  9.  
  10. /* Exports:
  11.  *   void _initialize_dynamic_libs()
  12.  *   void _finalize_dynamic_libs()
  13.  *
  14.  * In case of static linking these are just dummy functions.
  15.  * In case of dynamic shared objects (libraries):
  16.  * The dynamic shared objects are already linked with the main program and 
  17.  * control was passed from `start' (in `crt0.o') to `_main' and from that
  18.  * to `__main' in `drt0.o'.
  19.  *
  20.  * The functions here have to do the _initialization_ and _finalization_ of
  21.  * all the dynamic shared objects (the initialization and finalization of the 
  22.  * main program is done by the calling function).
  23.  */
  24.  
  25.  
  26. #ifndef DYNAMIC_LIBS
  27. /*
  28.  * static case
  29.  */
  30.  
  31. void _initialize_dynamic_libs() {}
  32. void _finalize_dynamic_libs() {}
  33.  
  34. #else
  35. /*
  36.  * dynamic case
  37.  *
  38.  *   
  39.  */
  40.  
  41. #include <sys/types.h>
  42. #include <link.h>
  43. #include <dlfcn.h>
  44. #include <malloc.h>
  45. #include "dldefs.h"
  46.  
  47. extern struct link_dynamic _DYNAMIC;
  48.  
  49. /* Unix linker looks up global symbols in first one down the line  (?? H.S.)*/
  50. const char CTOR_LIST_NAME[] = "___CTOR_LIST__";
  51. const char DTOR_LIST_NAME[] = "___DTOR_LIST__";
  52.  
  53. extern int * __function_list_addr;
  54.  
  55. /* "Handles" to the dynamic shared objects can be obtained via the _DYNAMIC 
  56.  * structure; but since be have to do finalization in the opposite direction
  57.  * as initialization, we construct a doubly linked list of these handles.
  58.  */
  59.  
  60. struct _sll {
  61.     struct _sll* next;
  62.     struct _sll* prev;
  63.     struct link_map* lmp;
  64. };
  65.  
  66. #define NULLP (struct _sll*)0
  67.  
  68. static struct _sll* _sll_head = NULLP;
  69. static struct _sll* _sll_tail = NULLP;
  70.  
  71. static inline
  72. void new(struct link_map* nlmp)
  73. {
  74.     struct _sll * this = (struct _sll *) malloc (sizeof (struct _sll));
  75.  
  76.     this->lmp  = nlmp;
  77.     this->next = NULLP;
  78.     this->prev = NULLP;
  79.  
  80.     if( !_sll_head ) {
  81.     _sll_head = this;
  82.     _sll_tail = this;
  83.     } else {
  84.     this->prev = _sll_tail;
  85.     _sll_tail->next = this;
  86.     _sll_tail = this;
  87.     }
  88. }
  89.  
  90. static
  91. void build_sll()
  92. /*
  93.  *  -- Build doubly linked list of dynamic libraries
  94.  */
  95. {
  96.     /* extern struct link_dynamic _DYNAMIC; */
  97.     struct link_dynamic_2* ldd;
  98.     struct link_map* lmp;
  99.  
  100.     ldd  = _DYNAMIC.ld_un.ld_2;
  101.  
  102.     for( lmp = ldd->ld_loaded; lmp; lmp = lmp->lm_next ) {
  103.     new (lmp);
  104.     }
  105. }
  106.  
  107. static
  108. void delete_sll()
  109. /*
  110.  *  -- Delete doubly linked list of dynamic libraries
  111.  */
  112. {
  113.     struct _sll * this = _sll_tail;
  114.     struct _sll * prev;
  115.  
  116.     while ( this ) {
  117.             prev = this->prev;
  118.         free ( this);
  119.         this = prev;
  120.     }
  121. }
  122.  
  123.  
  124. static
  125. void __do_dynamic_lib( struct _sll * sllp,
  126.                char * fname,  const char* lname, int forwardp )
  127. /* 
  128.  *   -- Fake out dlsym() into giving me the names of any initialization or
  129.  *      finalization functions and call them.
  130.  */
  131. {
  132.  
  133.     struct _sll * p    = sllp;
  134.     void *        dobj;
  135.     void_fn       f;
  136.  
  137.     while( p ) {
  138.  
  139.     /* Set up the dl_object first */
  140.  
  141.     dobj = dlopen( p->lmp->lm_name, 1 );
  142.  
  143.     /* Call dlsym() looking for the function symbol. */
  144.  
  145.     f = (void_fn)dlsym( dobj, fname);
  146.  
  147.     /*
  148.      * Because the Unix dynamic linker resolves global
  149.      * symbols in the shared library to symbols in main,
  150.      * we need to use this kludge to get the address of
  151.      * the function list to the initialization and
  152.      * finalization functions. If there is no symbol
  153.      * for the CTOR or DTOR lists, we call the function
  154.      * anyway, because the library creator may have written their
  155.      * own initialization function.
  156.     */
  157.  
  158.     __function_list_addr = (int*)dlsym((void*)dobj,lname);
  159.  
  160.     /* If nonnull, call the function. */
  161.  
  162.     if( f ) {
  163.         f();
  164.     }
  165.  
  166.     /*Increment to next list entry, depending on flag.*/
  167.  
  168.     p = ( forwardp ? p->next : p->prev);
  169.     }
  170. }
  171.     
  172. void _initialize_dynamic_libs()
  173. /* _initialize_dynamic_libs
  174.  *
  175.  *  -- Initialize the dynamically linked libraries.
  176.  */
  177. {
  178.     build_sll();
  179.  
  180.     __do_dynamic_lib( _sll_tail, INIT_FUN_NAME, CTOR_LIST_NAME, 0);
  181.  
  182.     delete_sll();
  183. }
  184.  
  185.  
  186. void _finalize_dynamic_libs()
  187. /*
  188.  * _finalize_dynamic_libs
  189.  *
  190.  *  -- Finalize the dynamically linked libraries.
  191.  */
  192. {
  193.     /* Have to rebuild sll list, the user may have added something */
  194.     _sll_head = _sll_tail = NULLP;
  195.  
  196.     build_sll();
  197.  
  198.     __do_dynamic_lib( _sll_head, FINI_FUN_NAME, DTOR_LIST_NAME, 1);
  199.  
  200.     delete_sll();
  201. }
  202.  
  203. #endif /* DYNAMIC_LIBS */
  204.